package com.dragon.common.spring.business.base;

import com.chris.dev.base.libs.v1.http.results.PageResult;
import com.dragon.common.spring.business.base.jpa.BaseRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @param <E>          实体类
 * @param <P>          Create参数类
 * @param <U>          Update参数类
 * @param <F>          搜索参数类
 * @param <O>          排序参数类
 * @param <R>          Result结果类
 * @param <Repository> 仓库类
 * @param <Converter>  转换器类
 * @author Chris Chan
 * Create on 2023-04-13 10:30
 * Use for: 基本CRUD服务
 * Explain:
 * @author Chris Chan
 * Create On 2025/7/29 下午12:04
 * Use for: 基本CRUD服务
 * Explain:
 */
public interface BaseCrudService<E, P, U, F,O, R, Repository extends BaseRepository<E>, Converter extends BaseConverter<E, P, U, R>> {
    /**
     * 获取仓库
     *
     * @return 仓库
     */
    Repository getRepository();

    /**
     * 获取转换器
     *
     * @return 转换器
     */
    Converter getConverter();

    /**
     * 新增
     *
     * @param param Create参数
     * @return 是否新增成功
     */
    @Transactional
    default boolean add(P param) {
        E entity = this.getConverter().fromParam(param);
        this.getRepository().saveAndFlush(entity);
        return true;
    }

    /**
     * 新增列表
     *
     * @param paramList Create参数列表
     * @return 是否新增成功
     */
    @Transactional
    default boolean addList(List<P> paramList) {
        List<E> entityList = this.getConverter().fromParamList(paramList);
        this.getRepository().saveAllAndFlush(entityList);
        return true;
    }

    /**
     * 更新
     *
     * @param param Update参数
     * @return 是否更新成功
     */
    @Transactional
    default boolean update(U param) {
        E entity = this.getConverter().fromUpdateParam(param);
        this.getRepository().saveAndFlush(entity);
        return true;
    }

    /**
     * 删除
     * 按照ID删除
     *
     * @param id ID
     * @return 是否删除成功
     */
    @Transactional
    default boolean remove(Long id) {
        this.getRepository().deleteById(id);
        return true;
    }

    /**
     * 删除
     * 按照ID列表删除
     *
     * @param idList ID列表
     * @return 是否删除成功
     */
    @Transactional
    default boolean removeAllByIdList(List<Long> idList) {
        this.getRepository().deleteAllByIdInBatch(idList);
        return true;
    }

    /**
     * 删除
     * 按照ID集合删除
     *
     * @param idSet ID集合
     * @return 是否删除成功
     */
    @Transactional
    default boolean removeAllByIdSet(Set<Long> idSet) {
        this.getRepository().deleteAllByIdInBatch(idSet);
        return true;
    }

    /**
     * 删除
     * 按照ID数组删除
     *
     * @param ids ID数组
     * @return 是否删除成功
     */
    @Transactional
    default boolean removeAllByIds(Long[] ids) {
        this.getRepository().deleteAllByIdInBatch(Arrays.asList(ids));
        return true;
    }

    /**
     * 查询
     * 按照ID查询
     *
     * @param id ID
     * @return Result结果
     */
    default R findById(Long id) {
        return this.getRepository().findById(id).map((entity) -> this.getConverter().toResult(entity)).orElse(null);
    }

    /**
     * 查询
     * 按照ID列表查询
     *
     * @param idList ID列表
     * @return Result结果列表
     */
    default List<R> findAllByIdList(List<Long> idList) {
        return Optional.of(this.getRepository().findAllById(idList))
                .map(list -> list.stream()
                        .map(entity -> this.getConverter().toResult(entity))
                        .collect(Collectors.toList()))
                .orElse(new ArrayList<>());
    }

    /**
     * 查询
     * 按照ID集合查询
     *
     * @param idSet ID集合
     * @return Result结果列表
     */
    default List<R> findAllByIdSet(Set<Long> idSet) {
        return this.findAllByIdList(new ArrayList<>(idSet));
    }

    /**
     * 查询
     * 按照ID数组查询
     *
     * @param ids ID数组
     * @return Result结果列表
     */
    default List<R> findAllByIds(Long[] ids) {
        return this.findAllByIdList(Arrays.asList(ids));
    }

    /**
     * 查询
     * 按照所有查询
     *
     * @return Result结果列表
     */
    default List<R> findAll() {
        return Optional.of(getRepository().findAll())
                .map(list -> list.stream()
                        .map(entity -> getConverter().toResult(entity))
                        .collect(Collectors.toList()))
                .orElse(new ArrayList<>());
    }

    /**
     * 查询
     * 分页查询
     *
     * @param page     页码
     * @param pageSize 每页数量
     * @return Result结果分页
     * 前端调用页码从1开始
     * 但是Jpa的分页从0开始
     */
    default PageResult<R> findPage(int page, int pageSize) {
        int realPage = page > 0 ? page - 1 : 0;
        PageRequest pageRequest = PageRequest.of(realPage, pageSize);
        Page<E> all = this.getRepository().findAll(pageRequest);
        return Optional.of(all)
                .map(pg -> this.getConverter().toResultPage(pg))
                .orElse(PageResult.buildNull());
    }

    /**
     * 查询
     * 排序分页查询
     *
     * @param search   搜索参数
     * @param order    排序参数
     * @param page     页码
     * @param pageSize 每页数量
     * @return Result结果分页
     */
    default PageResult<R> searchSortPage(F search, O order, int page, int pageSize) {
        return this.findPage(page, pageSize);
    }
}
